package com.tf_cut.backend.request.util;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;

import com.tf_cut.backend.util.MybankConstants;


/**
 * 日志工具类
 */
public class MybankLogger {

    private static final Log clog = LogFactory.getLog("sdk.comm.error");
    private static final Log blog = LogFactory.getLog("sdk.biz.error");
    private static final Log blogDebug = LogFactory.getLog("sdk.biz.debug");

    private static String osName = System.getProperties().getProperty("os.name");
    private static String ip;

    static {
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    private static boolean needEnableLogger = true;

    public static void setNeedEnableLogger(boolean needEnableLogger) {
        MybankLogger.needEnableLogger = needEnableLogger;
    }

    public static void setIp(String ip) {
        MybankLogger.ip = ip;
    }

    public static Boolean isBizDebugEnabled() {
        return blog.isDebugEnabled();
    }

    /**
     * 业务错误日志
     */
    public static void logBizError(Throwable t) {
        if (!needEnableLogger) {
            return;
        }
        blog.error(t);
    }

    public static void logCommError(Exception e, String serverUrl, String xmlContent, String apiFunction, String apiVersion) {
        if (!needEnableLogger) {
            return;
        }
        logCommErrorHandle(e, null, serverUrl, xmlContent, apiFunction, apiVersion);
    }

    public static void logCommError(Exception e, HttpURLConnection conn, String xmlContent, String apiFunction, String apiVersion) {
        if (!needEnableLogger) {
            return;
        }
        logCommErrorHandle(e, conn, null, xmlContent, apiFunction, apiVersion);
    }

    /**
     * 通讯错误日志
     */
    private static void logCommErrorHandle(Exception e, HttpURLConnection conn, String serverUrl, String xmlContent,
                                      String apiFunction, String apiVersion) {
        String urlStr = null;
        String rspCode = MybankConstants.NULL_STRING;
        if (conn != null) {
            try {
                urlStr = conn.getURL().toString();
                rspCode = "HTTP_ERROR_" + conn.getResponseCode();
            } catch (IOException ioe) {
            }
        } else {
            urlStr = serverUrl;
            rspCode = MybankConstants.NULL_STRING;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern(MybankConstants.LOG_DATE_TIME_FORMAT)));
        sb.append("^_^");
        sb.append(apiFunction);
        sb.append("^_^");
        sb.append(apiVersion);
        sb.append("^_^");
        sb.append(ip);
        sb.append("^_^");
        sb.append(osName);
        sb.append("^_^");
        sb.append(urlStr);
        sb.append("^_^");
        sb.append(xmlContent);
        sb.append("^_^");
        sb.append(rspCode);
        sb.append("^_^");
        sb.append((e.getMessage() + MybankConstants.NULL_STRING).replaceAll("\r\n", " "));
        clog.error(sb.toString());
    }

    /**
     * 通讯错误日志
     */
    public static void logCommError(Exception e, HttpResponse response, String serverUrl, String entityString,
                                    String apiFunction, String apiVersion) {
        String rspCode = response != null ?  "HTTP_ERROR_" + response.getStatusLine().getStatusCode(): MybankConstants.NULL_STRING;

        StringBuilder sb = new StringBuilder();
        sb.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern(MybankConstants.LOG_DATE_TIME_FORMAT)));
        sb.append("^_^");
        sb.append(apiFunction);
        sb.append("^_^");
        sb.append(apiVersion);
        sb.append("^_^");
        sb.append(ip);
        sb.append("^_^");
        sb.append(osName);
        sb.append("^_^");
        sb.append(serverUrl);
        sb.append("^_^");
        sb.append(entityString);
        sb.append("^_^");
        sb.append(rspCode);
        sb.append("^_^");
        sb.append((e.getMessage() + "").replaceAll("\r\n", " "));
        clog.error(sb.toString());
    }

    /**
     * 业务/系统错误日志
     */
    public static void logBizError(String rspContent, Map<String, Long> costTimeMap) {
        if (!needEnableLogger) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern(MybankConstants.LOG_DATE_TIME_FORMAT)));
        sb.append("^_^");
        sb.append(rspContent);
        sb.append("^_^");
        sb.append(costTimeMap.get("prepareCostTime"));
        sb.append("ms,");
        sb.append(costTimeMap.get("requestCostTime"));
        sb.append("ms,");
        sb.append(costTimeMap.get("postCostTime"));
        sb.append("ms");
        blog.error(sb.toString());
    }

    /**
     * 记录一次正常服务调用处理结果
     */
    public static void logBizSummary(Map<String, Object> rt, Map<String, Long> costTimeMap) {
        if (!needEnableLogger) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        sb.append("Summary");
        sb.append("^_^");
        sb.append("客户端发送报文:");
        sb.append((String) rt.get("requestContent"));
        sb.append("^_^");
        sb.append("\t\n");
        sb.append("客户端接收报文:");
        sb.append((String) rt.get("rspContent"));
        sb.append("^_^");
        sb.append(costTimeMap.get("prepareCostTime"));
        sb.append("ms,");
        sb.append(costTimeMap.get("requestCostTime"));
        sb.append("ms,");
        sb.append(costTimeMap.get("postCostTime"));
        sb.append("ms");
        blogDebug.debug(sb.toString());
    }
}